﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace Wicresoft.EKA.NRemedy.Linq
{
    // 
    // Listing 12-23
    // 
    public abstract class BaseQueryProvider : IQueryProvider
    {

        IQueryable<S> IQueryProvider.CreateQuery<S>(Expression expression)
        {
            return new ARSet<S>(this, expression);
        }

        IQueryable IQueryProvider.CreateQuery(Expression expression)
        {
            Type elementType = TypeSystem.GetElementType(expression.Type);
            try
            {
                return (IQueryable)Activator.CreateInstance(typeof(ARSet<>).MakeGenericType(elementType), new object[] { this, expression });
            }
            catch (TargetInvocationException tie)
            {
                throw tie.InnerException;
            }
        }

        public TResult Execute<TResult>(Expression expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            if (!typeof(IQueryable<TResult>).IsAssignableFrom(expression.Type))
            {
                throw new ArgumentException("Argument expression is not valid");
            }
            return (TResult)this.Execute(expression);
        }

        public abstract object Execute(Expression expression);

        public abstract string GetQueryText(Expression expression);
    }

}
